#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "log.hpp"
#include"Calculate.hpp"
using cal_func = std::function<Respond(const Request&)>;
using namespace LogMudule;

// pacakge -- 12\r\n{json}\r\n
class Parse
{
public:
  Parse(cal_func cal):_cal(cal)
  {}
  std::string Entry(std::string &pacakge)
  {
    LOG(LogLevel::DEBUG)<<"对pacakge进行解析"<<pacakge;
    // 1.判断pacakge是否完整 然后decode
    std::string message;
    std::string respstr;
    while (Decode(pacakge, &message))
    {
      // 如果提取为空返回空串
      // message--json
      if (message.empty())
        break;
      // 2.反序列化message 得到req
      Request req;
      if (!req.DeSerialization(message))
        break;
      // 3.调用cla函数 得到结果 resp
      Respond resp;
      resp = _cal(req);
      LOG(LogLevel::DEBUG)<<"计算函数调用成功";
    // 4.序列化 resp
      std::string res;
      resp.Serialization(res);
      // 5.对resp添加报头 encode
      Encode(res);
      // 6.拼接好返回给网络层
      respstr+=res;
    }
    return respstr;
  }
  private:
    cal_func _cal;
};


int main()
{
  ENABLE_CONSOLE_LOG();
  // 架构分为三层 三层之间通过回调函数来进行联系
  // 1.计算器层 接受到解析层解析后的结构化对象 进行计算并给出结果
  // 2.解析层  收到网络层发来的pacakge后进行解析(反序列化)   拿到计算的结果后再进行序列化添加报头传给网络层
  // 3.网络通信层  收到客户端发到的请求后通过解析层的回调函数把序列化的pacakge发过去 收到解析层返回的结果后再发送到客户端
  Cal mycal;
  Parse myparse([&mycal](const Request &req){
    return mycal.Excute(req);
  });
  std::unique_ptr<TcpServer> tcps = std::make_unique<TcpServer>([&myparse](std::string &pacakge){
    return myparse.Entry(pacakge);
  });
  tcps->Init();
  tcps->Start();
  return 0;
}